<?php
    namespace Core\ORM;
    /**
     * Modele d'objet pour tout les Modeles de l'application
     *
     * @author mpetrini
     */
    abstract class Modele extends \Core\ORM\ORMClasse {
        /**
        *
        * @var int $id
        */
        protected $id;
        
        /**
        * Constructeur complet
        * 
        * @param int $id
        *         
        * @return void
        */
        public function __construct($id) {
            $this->setId($id);
        }
        /**
        * Permet l'ajout d'une Instance dans la BDD
        * 
        * @return \Core\ORM\Modele
        */
        public function ajout() {
            $requete = new \Core\ORM\Requete\Insert($this);
            $this->id = $requete->execution();
            return $this;
        }
        /**
        * Permet la modification d'une Instance dans la BDD
        * 
        * @return boolean
        */
        public function modification() {
            $table = new \Core\ORM\Table(get_class($this));
            $requete = new \Core\ORM\Requete\Update($this);
            if(method_exists($this, "setDateModification")) {
                $this->setDateModification(new DateTime());
            }
            $requete->ajoutWhere($table, 'id', $this->id);
            return (boolean)$requete->execution();
        }
        /**
        * Permet la suppression d'une Instance dans la BDD
        * 
        * @return boolean
        */
        public function suppression() {
            $table = new \Core\ORM\Table(get_class($this));
            if(property_exists($this, 'valide')) {
                $this->setValide(false);
            }
            else {
                $requete = new \Core\ORM\Requete\Delete($table);
            }
            $requete->ajoutWhere($table, 'id', $this->id);
            return (boolean)$requete->execution();
        }
        
        /**
        * Permet de créer des Objets hérités du Modèle grâce à leurs ID
        * 
        * @param mixed $mixed
        * @param boolean $unique //Savoir si on récupère un ou plusieurs éléments
        * 
        * @return \Core\ORM\Modele|\Core\ORM\Modele[]
        */
        public static function recherche($mixed, $unique = false) {
            $tabRetour = array();
            //On récupère le nom de l'Objet que l'on souhaite récupérer
            $classe = get_called_class();
            //On instancie le tableau qui va récupérer toutes les tables que l'on souhaite utiliser
            $tables = new \Utils\Tableau;
            //On crée l'objet qui va permettre de faire la requête
            $requete = new \Core\ORM\Requete\Select();
            
            //On ajoute la Table de l'Objet que l'on souhaite récupérer
            $table = new \Core\ORM\Table($classe);
            $tables[$classe]["objet"] = $table;
            $requete->ajoutTable($table);
            //Si le paramètre est une chaine c'est que l'utilisateur veut faire une recherche manuelle
            if(is_string($mixed)) {
                $requete->setWhere($mixed);
            }
            //Sinon si le paramètre n'est pas un tableau, alors on recherche par rapport à l'ID
            else if(!is_array($mixed)) {
                $unique = true;
                $requete->ajoutWhere($table, 'id', $mixed);
            }
            else if(is_array($mixed)) {
                foreach($mixed as $index => $m) {
                    $requete->ajoutWhere($table, $index, $m);
                }
            }
            try {
                $resultat = $requete->execution();
            } catch (\Core\ORM\Exception\RequeteException $e) {
                //Si un erreur s'est produit et que l'on est en Dev ou en Test on affiche l'erreuyr
                if(__STATUT__ === 'Dev'  || __STATUT__ === 'Test') {
                    echo $e;
                }
            }
            if(isset($resultat)) {
                foreach($resultat as $r) {
                    if($unique) {
                        return self::creationObjet($classe, $r);
                    }
                    else {
                        $tabRetour[] = self::creationObjet($classe, $r);
                    }
                }
                return $tabRetour;
            }
            return null;
        }
        /**
        * Permet de créer des Objets hérités du Modèle d'un Hérité
        * 
        * @return \Core\ORM\Modele[]
        */
        public static function rechercheTout() {
            //On récupère le nom de l'Objet que l'on souhaite récupérer
            $classe = get_called_class();
            //On instancie le tableau qui va récupérer toutes les tables que l'on souhaite utiliser
            $tables = new \Utils\Tableau;
            //On crée l'objet qui va permettre de faire la requête
            $requete = new \Core\ORM\Requete\Select();
            
            //On ajoute la Table de l'Objet que l'on souhaite récupérer
            $table = new \Core\ORM\Table($classe);
            $tables[$classe]["objet"] = $table;
            $requete->ajoutTable($table);
            $resultat = $requete->execution();
            $tabRetour = array();
            foreach($resultat as $r) {
                $tabRetour[] = self::creationObjet($classe, $r);
            }
            return $tabRetour;
        }
        
        public final function getId() {return $this->id;}
        public final function setId($id) {$this->id=intval($id);}
    }
?>
